package org.bitseal.crypt; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.spongycastle.crypto.digests.RIPEMD160Digest; /** * Provides methods for several hashing functions based on SHA-256 * * @author Sebastian Schmidt, modified by Jonathan Coe */ public class SHA256 { /** * Calculates the double SHA-256 hash of a given byte[]. */ public static byte[] doubleDigest(byte[] input) { return doubleDigest(input, 0, input.length); } /** * Calculates the SHA-256 hash of the given byte range, and then hashes the resulting hash again. This is * standard procedure in BitCoin. The resulting hash is in big endian form. */ public static byte[] doubleDigest(byte[] input, int offset, int length) { try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.update(input, offset, length); byte[] first = digest.digest(); return digest.digest(first); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("NoSuchAlgorithmException occurred in DigestSHA256.doubleDigest()", e); } } /** * Calculates RIPEMD160(SHA256(input)). This is used in Address calculations. */ public static byte[] sha256hash160(byte[] input) { try { byte[] sha256 = MessageDigest.getInstance("SHA-256").digest(input); RIPEMD160Digest digest = new RIPEMD160Digest(); digest.update(sha256, 0, sha256.length); byte[] out = new byte[20]; digest.doFinal(out, 0); return out; } catch (NoSuchAlgorithmException e) { throw new RuntimeException("NoSuchAlgorithmException occurred in DigestSHA256.sha256hash160()", e); } } /** * Calculates the HmacSHA256 from the given key and data. * * @param data - A byte[] containing the data. * @param key - A byte[] containing the key. * * @return A byte[] containing the HmacSHA256. */ public static byte[] hmacSHA256(byte[] data, byte[] key) { Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider()); try { Mac mac = Mac.getInstance("HmacSHA256", "SC"); mac.init(new SecretKeySpec(key, "HmacSHA256")); return mac.doFinal(data); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("NoSuchAlgorithmException occurred in hmacSHA256.sha256hash160()", e); } catch (NoSuchProviderException e) { throw new RuntimeException("NoSuchProviderException occurred in hmacSHA256.sha256hash160()", e); } catch (InvalidKeyException e) { throw new RuntimeException("InvalidKeyException occurred in hmacSHA256.sha256hash160()", e); } } }